home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / c-lang / vbcc.lha / vbcc / loop.c < prev    next >
C/C++ Source or Header  |  1996-05-15  |  10KB  |  247 lines

  1. /*  $VER: vbcc (loop.c) V0.3     */
  2. /*  schleifenorientierte Optimierungen  */
  3.  
  4. #include "opt.h"
  5.  
  6. int report_weird_code;
  7.  
  8. void loops(struct flowgraph *fg,int footers)
  9. /*  kennzeichnet Schleifen im Flussgraph; wenn footers!=0 werden darf eine  */
  10. /*  Schleife nur einen gemeinsamen Austrittspunkt haben                     */
  11. {
  12.     int i,start,end;struct flowlist *lp;struct flowgraph *g,*loopend;
  13.     if(DEBUG&1024) printf("searching loops\n");
  14.     g=fg;
  15.     while(g){
  16.         start=g->index;
  17.         end=-1;
  18.         lp=g->in;
  19.         while(lp){
  20.             if(lp->graph->branchout==g||!lp->graph->end||lp->graph->end->code!=BRA){
  21.                 i=lp->graph->index;
  22.                 if(i>=start&&i>end){ end=i;loopend=lp->graph; }
  23.             }
  24.             lp=lp->next;
  25.         }
  26.         if(end>=0){
  27.         /*  Schleife oder etwas aehnliches  */
  28.             struct flowgraph *p=g;
  29.             if(DEBUG&1024) printf("found possible loop from blocks %d to %d\n",start,end);
  30.             if(goto_used){
  31.                 if(DEBUG&1024) printf("have to check...\n");
  32.                 do{
  33.                     if(!p||p->index>end) break;
  34.                     /*  testen, ob aus der Schleife gesprungen wird */
  35.                     if(p->branchout){
  36.                         i=p->branchout->index;
  37.                         if(i<start){
  38.                             if(report_weird_code){error(175);report_weird_code=0;}
  39.                             end=-1;
  40.                             break;
  41.                         }
  42.                         if(i>end&&(DEBUG&1024)){
  43.                             puts("jump out of loop");
  44.                             if(p->branchout!=loopend->normalout){
  45.                                 puts("no break");
  46.                                 if(p->branchout->start->typf!=return_label) puts("no return");
  47.                             }
  48.                         }
  49.                         if(i>end&&p->branchout!=loopend->normalout&&p->branchout->start->typf!=return_label){
  50.                         /*  Sprung zu anderem als dem normalen Austritt oder return */
  51.                             end=-1;
  52.                             break;
  53.                         }
  54.                     }
  55.                     /*  testen, ob in die Schleife gesprungen wird  */
  56.                     lp=p->in;
  57.                     while(lp){
  58.                         if(lp->graph->branchout==p){
  59.                             i=lp->graph->index;
  60.                             if(i<start||i>end){
  61.                                 if(report_weird_code){error(175);report_weird_code=0;}
  62.                                 end=-1;
  63.                                 break;
  64.                             }
  65.                         }
  66.                         lp=lp->next;
  67.                     }
  68.                     if(p->index==end) break;
  69.                     p=p->normalout;
  70.                 }while(1);
  71.             }else{
  72.                 if(DEBUG&1024) printf("must be a loop, because there was no goto\n");
  73.             }
  74.         }
  75.         if(end>=0){
  76.             if(DEBUG&1024) printf("confirmed that it is a loop\n");
  77.             g->loopend=loopend;
  78.         }
  79.         g=g->normalout;
  80.     }
  81. }
  82.  
  83. struct flowgraph *create_loop_headers(struct flowgraph *fg)
  84. /*  fuegt vor jede Schleife einen Kopf-Block ein, wenn noetig   */
  85. /*  braucht aktive Variablen und kann einen Block mehrmals in   */
  86. /*  der ->in Liste eintragen                                    */
  87. {
  88.     struct flowgraph *g,*last,*new,*rg=fg;
  89.     struct IC *lic;
  90.     if(DEBUG&1024) printf("creating loop-headers\n");
  91.     g=fg;last=0;
  92.     while(g){
  93.         new=0;
  94.         if(g->loopend){
  95.             if(!last){
  96.                 struct flowlist *lp;
  97.                 new=mymalloc(sizeof(struct flowgraph));
  98.                 rg=new;
  99.                 new->in=0;
  100.                 new->start=new->end=0;
  101.                 lp=mymalloc(sizeof(struct flowlist));
  102.                 lp->graph=new;
  103.                 lp->next=g->in;
  104.                 g->in=lp;
  105.             }else{
  106.                 struct flowlist *lp,*nl,**ls;
  107.                 new=mymalloc(sizeof(struct flowgraph));
  108.                 last->normalout=new;
  109.                 lic=mymalloc(ICS);
  110.                 new->start=new->end=lic;
  111.                 lic->code=LABEL;
  112.                 lic->typf=++label;
  113.                 lic->q1.flags=lic->q2.flags=lic->z.flags=0;
  114.                 lic->q1.am=lic->q2.am=lic->z.am=0;
  115.                 last->end->next=lic;    /*  kann nicht leer sein, da sonst branchout nicht 0 waere  */
  116.                 lic->prev=last->end;
  117.                 g->start->prev=lic;
  118.                 lic->next=g->start;
  119.                 lp=g->in;ls=&new->in;
  120.                 while(lp){
  121.                     if(lp->graph&&lp->graph->index<g->index){
  122.                     /*  Eintritt von oben soll in den Kopf  */
  123.                         nl=mymalloc(sizeof(struct flowlist));
  124.                         nl->graph=lp->graph;
  125.                         nl->next=0;
  126.                         (*ls)=nl;
  127.                         ls=&nl->next;
  128.                         if(lp->graph->branchout==g){
  129.                             if(DEBUG&1024) printf("changing branch\n");
  130.                             if(lp->graph->end->code<BEQ||lp->graph->end->code>BRA) ierror(0);
  131.                             lp->graph->end->typf=lic->typf;
  132.                             lp->graph->branchout=new;
  133.                         }
  134.                         lp->graph=new;
  135.                     }
  136.                     lp=lp->next;
  137.                 }
  138.                 if(!new->in) ierror(0);
  139.             }
  140.             if(new){
  141.                 if(DEBUG&1024) printf("must insert loop-header before block %d\n",g->index);
  142.                 basic_blocks++;
  143.                 new->branchout=0;
  144.                 new->loopend=0;
  145.                 new->index=-1;
  146.                 new->normalout=g;
  147.                 new->calls=0;
  148.                 new->loop_calls=0;
  149.                 new->rd_in=new->rd_out=new->rd_kill=new->rd_gen=0;
  150.                 new->ae_in=new->ae_out=new->ae_kill=new->ae_gen=0;
  151.                 new->cp_in=new->cp_out=new->cp_kill=new->cp_gen=0;
  152.                 new->av_in=mymalloc(vsize);
  153.                 new->av_out=mymalloc(vsize);
  154.                 new->av_gen=mymalloc(vsize);
  155.                 new->av_kill=mymalloc(vsize);
  156.                 memset(new->av_gen,0,vsize);
  157.                 memset(new->av_kill,0,vsize);
  158.                 memcpy(new->av_out,g->av_in,vsize);
  159.                 memcpy(new->av_in,g->av_in,vsize);
  160.                 memcpy(&new->regv,&g->regv,sizeof(new->regv));
  161.                 memcpy(&new->regused,&g->regused,sizeof(new->regused));
  162.             }
  163.         }
  164.         last=g;
  165.         g=g->normalout;
  166.     }
  167.     return(rg);
  168. }
  169. struct flowgraph *create_loop_footers(struct flowgraph *fg)
  170. /*  fuegt hinter jede Schleife einen Austritts-Block ein, wenn noetig   */
  171. /*  braucht aktive Variablen und kann einen Block mehrmals in der ->in  */
  172. /*  Liste eintragen                                                     */
  173. {
  174.     struct flowgraph *g,*loopend,*out,*new;
  175.     struct IC *lic;
  176.     if(DEBUG&1024) printf("creating loop-footers\n");
  177.     g=fg;
  178.     while(g){
  179.         new=0;
  180.         loopend=g->loopend;
  181.         if(loopend){
  182.             struct flowlist *lp,*nl,**ls;
  183.             out=loopend->normalout;
  184.             new=mymalloc(sizeof(struct flowgraph));
  185.             new->normalout=out;
  186.             loopend->normalout=new;
  187.             lic=mymalloc(ICS);
  188.             new->start=new->end=lic;
  189.             lic->code=LABEL;
  190.             lic->typf=++label;
  191.             lic->q1.flags=lic->q2.flags=lic->z.flags=0;
  192.             lic->q1.am=lic->q2.am=lic->z.am=0;
  193.             if(out) lp=out->in; else {lp=0;new->in=0;}
  194.             ls=&new->in;
  195.             while(lp){
  196.                 if(lp->graph&&lp->graph->index<=loopend->index&&lp->graph->index>=g->index){
  197.                 /*  Austritt aus Schleife soll in den Fuss  */
  198.                     nl=mymalloc(sizeof(struct flowlist));
  199.                     nl->graph=lp->graph;
  200.                     nl->next=0;
  201.                     (*ls)=nl;
  202.                     ls=&nl->next;
  203.                     if(lp->graph->branchout==out){
  204.                         if(DEBUG&1024) printf("changing branch\n");
  205.                         if(lp->graph->end->code<BEQ||lp->graph->end->code>BRA) ierror(0);
  206.                         lp->graph->end->typf=lic->typf;
  207.                         lp->graph->branchout=new;
  208.                     }
  209.                     lp->graph=new;
  210.                 }
  211.                 lp=lp->next;
  212.             }
  213.             if(out&&!new->in) ierror(0);
  214.             if(DEBUG&1024) printf("must insert loop-footer after block %d\n",loopend->index);
  215.             basic_blocks++;
  216.             new->branchout=0;
  217.             new->loopend=0;
  218.             new->index=-2;
  219.             new->normalout=out;
  220.             new->calls=0;
  221.             new->loop_calls=0;
  222.             new->rd_in=new->rd_out=new->rd_kill=new->rd_gen=0;
  223.             new->ae_in=new->ae_out=new->ae_kill=new->ae_gen=0;
  224.             new->cp_in=new->cp_out=new->cp_kill=new->cp_gen=0;
  225.             new->av_in=mymalloc(vsize);
  226.             new->av_out=mymalloc(vsize);
  227.             new->av_kill=mymalloc(vsize);
  228.             new->av_gen=mymalloc(vsize);
  229.             memset(new->av_gen,0,vsize);
  230.             memset(new->av_kill,0,vsize);
  231.             if(out){
  232.                 memcpy(new->av_out,out->av_in,vsize);
  233.                 memcpy(new->av_in,out->av_in,vsize);
  234.             }else{
  235.                 memset(new->av_in,0,vsize);
  236.                 memset(new->av_out,0,vsize);
  237.             }
  238.             memcpy(&new->regv,&g->regv,sizeof(new->regv));
  239.             memcpy(&new->regused,&g->regused,sizeof(new->regused));
  240.             insert_IC_fg(new,loopend->end,lic);
  241.         }
  242.         g=g->normalout;
  243.     }
  244.     return(fg);
  245. }
  246.  
  247.